Imports FluentValidation
Imports FluentValidation.Resources
Imports System.ComponentModel
Imports System.Runtime.CompilerServices


Public Module IRuleBuilderOptionsExtensions

    ''' <summary>
    ''' Specifies a custom property name to use within the error message.
    ''' </summary>
    ''' <param name="rule">The current rule</param>
    ''' <returns></returns>
    <Extension()>
    Public Function WithDisplayName(Of T, TProperty)(ByVal rule As IRuleBuilderOptions(Of T, TProperty)) As IRuleBuilderOptions(Of T, TProperty)
        Return rule.Configure(Sub(config As FluentValidation.Internal.PropertyRule)
                                  Dim pi = GetType(T).GetProperty(config.PropertyName)
                                  If pi Is Nothing Then
                                      config.DisplayName = New StaticStringSource("PROPIEDAD DESCONOCIDA: " & config.PropertyName)
                                      Exit Sub
                                  End If
                                  Dim displayNames = pi.GetCustomAttributes(GetType(DisplayNameAttribute), True)
                                  If displayNames.Count > 0 Then
                                      config.DisplayName = New StaticStringSource(DirectCast(displayNames(0), DisplayNameAttribute).DisplayName())
                                  Else
                                      Dim metaDataTypes = GetType(T).GetCustomAttributes(GetType(System.ComponentModel.DataAnnotations.MetadataTypeAttribute), True)
                                      If metaDataTypes.Count > 0 Then
                                          Dim metaDataType = DirectCast(metaDataTypes(0), System.ComponentModel.DataAnnotations.MetadataTypeAttribute).MetadataClassType
                                          pi = metaDataType.GetProperty(config.PropertyName)
                                          If pi Is Nothing Then
                                              config.DisplayName = New StaticStringSource("(META)PROPIEDAD DESCONOCIDA: " & config.PropertyName)
                                              Exit Sub
                                          End If
                                          displayNames = pi.GetCustomAttributes(GetType(DisplayNameAttribute), True)
                                          If displayNames.Count > 0 Then
                                              config.DisplayName = New StaticStringSource(DirectCast(displayNames(0), DisplayNameAttribute).DisplayName())
                                          Else
                                              config.DisplayName = New StaticStringSource("(META)DISPLAY NAMES NO ENCONTRADOS PARA PROPIEDAD: " & config.PropertyName)
                                          End If
                                      Else
                                          config.DisplayName = New StaticStringSource("DISPLAY NAMES NO ENCONTRADOS PARA PROPIEDAD: " & config.PropertyName)
                                      End If
                                  End If
                              End Sub)
    End Function
End Module